<template>
    <div class="trant">
        <!-- 左边表格数据 -->
        <div class="trant-left">
            <p>未选中</p>
            <div class="trant-content" v-loading="loading">
                <div class="content-input">
                    <el-input
                        :placeholder="leftPlaceholder"
                        v-model="searchData.left.temp"
                        style="width:90%"
                        size="mini"
                        @keyup.enter.native="onSearch('left')"
                    ></el-input>
                    <el-button class="left-p" type="primary" icon="el-icon-search" @click="onSearch('left')"></el-button>
                </div>
                <div>
                    <el-table
                        ref="leftTable"
                        :data="leftTableDataStorage"
                        tooltip-effect="dark"
                        style="width: 100%"
                        :height="tableHeight"
                        :row-key="indexKey"
                        border
                        @select="leftHandleSelected"
                        @select-all="leftHandleSelected"
                    >
                        <el-table-column
                            type="selection"
                            width="40"
                            align="center"
                            :reserve-selection="true"
                            :selectable="selectable"
                        ></el-table-column>
                        <el-table-column
                            v-for="col in columns"
                            :key="col.prop"
                            :prop="col.prop"
                            :label="col.label"
                            show-overflow-tooltip
                        ></el-table-column>
                    </el-table>
                </div>
                <el-pagination
                    layout="total, prev, pager, next, sizes"
                    :total="page.left.total"
                    :page-sizes="page.pageSizes"
                    :page-size="page.left.pageSize"
                    :current-page="page.left.currentPage"
                    @current-change="changeLeftCurrentPage"
                    :pager-count="pagerCount"
                    @size-change="leftHandleSizeChange"
                    background
                ></el-pagination>
                <!-- <RiskPagination :paging="page.left" @page-change="changeLeftCurrentPage"></RiskPagination> -->
            </div>
        </div>

        <!-- 中间2个键 -->
        <div class="trant-but">
            <el-button
                type="primary"
                title="移动所有数据(≤5000)"
                icon="el-icon-d-arrow-right"
                :disabled="!leftTableDataStorage.length || isFullFiveThousands() || loading"
                @click="moveAllSelections('left', 'right')"
            ></el-button>
            <br />
            <el-button
                type="primary"
                title="移动勾选数据(≤5000)"
                icon="el-icon-arrow-right"
                :disabled="!leftTableDataStorage.length || !selections.leftSelectedArr.length || isFullFiveThousands() || loading"
                @click="moveSelections('left', 'right')"
            ></el-button>
            <br />
            <el-button
                type="primary"
                title="取消移动勾选数据(≤5000)"
                icon="el-icon-arrow-left"
                :disabled="!rightTableDataStorage.length || !selections.rightSelectedArr.length || loading"
                @click="moveSelections('right', 'left')"
            ></el-button>
            <br />
            <el-button
                type="primary"
                icon="el-icon-d-arrow-left"
                title="取消移动所有数据(≤5000)"
                :disabled="!rightTableDataStorage.length"
                @click="moveAllSelections('right', 'left')"
            ></el-button>
        </div>
        <!-- 右边表格数据 -->
        <div class="trant-right">
            <p>已选中</p>
            <div class="trant-content">
                <div class="content-input">
                    <el-input
                        :placeholder="rightPlaceholder || leftPlaceholder"
                        v-model="searchData.right.temp"
                        style="width:90%"
                        size="mini"
                        @keyup.enter.native="onSearch('right')"
                    ></el-input>
                    <el-button class="left-p" type="primary" icon="el-icon-search" @click="onSearch('right')"></el-button>
                </div>
                <div>
                    <el-table
                        ref="rightTable"
                        :data="filterRightTableData"
                        tooltip-effect="dark"
                        style="width: 100%"
                        :row-key="indexKey"
                        :height="tableHeight"
                        border
                        @select="rightHandleSelected"
                        @select-all="rightHandleSelected"
                    >
                        <el-table-column type="selection" width="40" align="center" :reserve-selection="true"></el-table-column>
                        <el-table-column
                            v-for="col in columns"
                            :key="col.prop"
                            :prop="col.prop"
                            :label="col.label"
                            show-overflow-tooltip
                        ></el-table-column>
                    </el-table>
                </div>
                <el-pagination
                    layout="total, prev, pager, next, sizes"
                    :total="filterRightTableAllData.length"
                    :page-sizes="page.pageSizes"
                    :page-size="page.right.pageSize"
                    :current-page.sync="page.right.currentPage"
                    :pager-count="pagerCount"
                    @size-change="rightHandleSizeChange"
                    background
                ></el-pagination>
                <!-- <RiskPagination :paging="page.right" @page-change="rightHandleSizeChange"></RiskPagination> -->
            </div>
        </div>
    </div>
</template>
<script lang="ts">
import { Component, Emit, Prop, Vue, Watch } from 'vue-property-decorator';
import { getCurrentPageData } from '@/utils/tools';
import RiskPagination from './risk-pagination.vue';

@Component({
    name: 'RiskTrantableCompanyPool',
    components: {
        RiskPagination,
    },
})
export default class RiskTrantableCompanyPool extends Vue {
    @Prop({ required: true }) url!: string;
    @Prop({ required: true }) url2!: string;
    @Prop({ required: true }) idName!: string;

    // 主键
    @Prop() indexKey: string;
    // 右边表格数据
    @Prop() rightTableData!: any[];
    // 左边、右边表格数据格式
    @Prop() columns: any;
    // 搜索输入框提示
    @Prop({ default: '请输入' }) leftPlaceholder?: string;
    @Prop() rightPlaceholder?: string;
    // 搜索的参数
    @Prop() searchNames?: string[];
    // 窗口是否最大化
    @Prop() fullscreenIs: boolean;
    // 左边接口请求数据慢优化需要用到公司池代码（编码）
    @Prop() grCode: string;
    // 右边改变要实时保存，为了左边显示更快
    pagerCount: number = 5;
    tableHeight: string = '350px';
    private changed = false;
    // 组件内部维护的数据
    private leftTableDataStorage: any[] = [];
    private rightTableDataStorage: any[] = [];
    // 搜索条件
    private searchData = {
        left: {
            data: '',
            temp: '',
        },
        right: {
            data: '',
            temp: '',
        },
    };
    // 分页
    private page = {
        pageSizes: [25, 50, 75, 100],
        left: {
            currentPage: 1,
            pageSize: 25,
            total: 0,
        },
        right: {
            currentPage: 1,
            pageSize: 25,
            total: 0,
        },
    };
    private loading = false;
    /* 选择数据数组 */
    private selections = {
        leftSelectedArr: [],
        rightSelectedArr: [],
    };
    /* 弹窗进来的数据长度 */
    private rightInitLen: number;
    /* 每次移动全部的最大数量限制 */
    private MOVE_MAX_LEN: number = 5000;
    /* 公司池的最大数量限制 */
    private POOL_MAX_LEN: number = 10000;

    /**
     * 获取左侧全部数据(不分页)
     */
    async getLeftTableAllData(needUpdataData = true) {
        const data = {
            filterCodes: this.rightTableDataStorage.map(item => item[this.indexKey]),
            keyName: this.searchData.left.data,
            paging: this.page.left,
            grCode: this.grCode,
        };
        this.loading = true;
        try {
            let result;
            // 实时更新数据
            if (needUpdataData) {
                let temp = await this.updateData();
                result = (await this.$axios.post(this.url, data)) as any;
            } else {
                result = (await this.$axios.post(this.url, data)) as any;
            }
            this.page.left.total = result.total;
            // this.leftTableDataStorage = list;
            this.leftTableDataStorage = result.list;
        } catch (e) {
            this.page.left.total = 0;
            this.leftTableDataStorage = [];
        } finally {
            this.loading = false;
        }
    }

    /**
     * 过滤获取右侧全部数据(不分页)
     */
    get filterRightTableAllData() {
        let data = this.rightTableDataStorage;
        let searchName = this.searchNames;
        // 匹配搜索功能
        if (searchName && searchName.length) {
            data = data.filter(item => {
                for (let i = 0; i < searchName.length; i++) {
                    let key = searchName[i];
                    let itemStr = item[key] ? String(item[key]) : '';
                    if (itemStr.indexOf(this.searchData.right.data) > -1) {
                        return true;
                    }
                }
                return false;
            });
        }
        return data;
    }

    /**
     * 过滤获取右侧当前页数据
     */
    get filterRightTableData() {
        let data = this.rightTableDataStorage;
        let searchName = this.searchNames;
        // 匹配搜索功能
        if (searchName && searchName.length) {
            data = data.filter(item => {
                for (let i = 0; i < searchName.length; i++) {
                    let key = searchName[i];
                    let itemStr = item[key] ? String(item[key]) : '';
                    if (itemStr.indexOf(this.searchData.right.data) > -1) {
                        return true;
                    }
                }
                return false;
            });
        }
        return getCurrentPageData(data, this.page.right.currentPage, this.page.right.pageSize);
    }

    /**
     * 监听两组表格数据
     */
    @Watch('rightTableData', { immediate: true, deep: true })
    async watchRightTableData() {
        this.rightTableDataStorage = JSON.parse(JSON.stringify(this.rightTableData));
        this.initParams();
        this.getLeftTableAllData(false);
    }

    @Watch('fullscreenIs', { immediate: true, deep: true })
    getfull() {
        if (this.fullscreenIs == false) {
            this.tableHeight = '300px';
        } else {
            this.tableHeight = '500px';
        }
    }

    /**
     * 搜索功能
     */
    onSearch(type: string) {
        if (this.searchData[type].temp === this.searchData[type].data) {
            return;
        }
        this.searchData[type].data = this.searchData[type].temp;
        if (type === 'left') {
            this.page.left.currentPage = 1;
            this.getLeftTableAllData();
        }
    }

    /**
     * 移动表格选中数据
     * @param from 数据来源
     * @param to   数据最终要调价的地方
     */
    moveSelections(from, to) {
        this.changed = true;
        let selections: any[] = [];
        this.page.left.currentPage = 1;
        this.page.right.currentPage = 1;
        if (from === 'left') {
            selections = this.selections.leftSelectedArr;
            let len = this.rightTableDataStorage.length;
            // 提前判断 右边已选中数量是不是即将超过10000
            // if (len + selections.length > this.POOL_MAX_LEN) {
            //     this.yh_message_box_error('已选中的数量即将超过' + this.POOL_MAX_LEN + '，数据量过大');
            //     this.loading = false;
            //     return;
            // }
            this.rightTableDataStorage.push(...selections);
            // console.log(this.rightTableDataStorage);
            const rightLen = this.rightTableDataStorage.length;
            // if (rightLen > this.POOL_MAX_LEN) {
            //     // 前端和后端进行判断
            //     this.yh_message_box_error('已选中的数量超过' + this.POOL_MAX_LEN + '，数据量过大');
            //     this.leftTableDataStorage = [];
            //     this.page.left.total = 0;
            //     return;
            // }
            // 获取左边新数据
            this.getLeftTableAllData();
        } else if (from === 'right') {
            selections = this.selections.rightSelectedArr;
            // 右移左
            const selectionKeys = selections.map(item => item[this.indexKey]);
            // 获取右边新的数据
            this.rightTableDataStorage = this.rightTableDataStorage.filter(item => {
                return !selectionKeys.includes(item[this.indexKey]);
            });
            // 获取左边新数据
            this.getLeftTableAllData();
        }

        // 清除选中项
        (this.$refs[from + 'Table'] as any).clearSelection();
        (this.$refs[to + 'Table'] as any).clearSelection();
        this.selections = {
            leftSelectedArr: [],
            rightSelectedArr: [],
        };
    }

    /**
     * 移动表格所有数据
     * @param from 数据来源
     * @param to   数据最终要调价的地方
     */
    async moveAllSelections(from, to) {
        this.changed = true;
        this.page.left.currentPage = 1;
        this.page.right.currentPage = 1;
        this.loading = true;
        if (from === 'right') {
            if (this.rightTableDataStorage.length > this.MOVE_MAX_LEN) {
                // 使数组减少5000条
                this.rightTableDataStorage.splice(0, this.MOVE_MAX_LEN);
            } else {
                this.rightTableDataStorage = [];
            }
            this.getLeftTableAllData();
        } else if (from === 'left') {
            try {
                const rightLen = this.rightTableDataStorage.length;
                // if (rightLen + this.MOVE_MAX_LEN > this.POOL_MAX_LEN) {
                //     this.yh_message_box_error('已选中的数量即将超过' + this.POOL_MAX_LEN + '，数据量过大');
                //     this.loading = false;
                //     return;
                // }
                if (this.page.left.total > this.MOVE_MAX_LEN) {
                    // 获取前5000条
                    const data = {
                        filterCodes: rightLen ? this.rightTableDataStorage : [],
                        keyName: this.searchData.left.data,
                        grCode: this.grCode,
                        paging: {
                            total: 0,
                            currentPage: 1,
                            pageSize: this.MOVE_MAX_LEN,
                        },
                    };
                    let result = (await this.$axios.post(this.url, data)) as any;
                    this.selections.leftSelectedArr = result.list;
                    this.moveSelections(from, to);
                } else {
                    this.page.left.total = 0;
                    this.leftTableDataStorage = [];
                    // 获取右边所有数据
                    const data = {
                        filterCodes: [],
                        keyName: this.searchData.left.data,
                        paging: {
                            total: 0,
                            currentPage: 1,
                            pageSize: 2147483647,
                        },
                    };
                    let result;
                    this.loading = true;
                    try {
                        result = (await this.$axios.post(this.url, data)) as any;
                    } catch (e) {
                        result.total = 0;
                        result.list = [];
                    } finally {
                        this.loading = false;
                    }
                    this.rightTableDataStorage = result.list;
                    // 更新数据，这个左侧数据总数小于5000情况，未测
                    this.getLeftTableAllData();
                }
            } catch (e) {
                this.rightTableDataStorage = [];
            }
        }

        // 清除选中项
        (this.$refs[from + 'Table'] as any).clearSelection();
        (this.$refs[to + 'Table'] as any).clearSelection();
        this.selections = {
            leftSelectedArr: [],
            rightSelectedArr: [],
        };
    }

    /**
     * 获取左边所有数据
     */
    getLeftAllData(): any[] {
        return this.leftTableDataStorage;
    }

    /**
     * 获取右边所有数据
     */
    getRightAllData(): any[] {
        return this.rightTableDataStorage;
    }

    getChanged() {
        return this.changed;
    }

    /**
     * 左边翻页
     */
    changeLeftCurrentPage(val) {
        this.page.left.currentPage = val;
        this.getLeftTableAllData(false);
    }

    /**
     * 初始化参数
     */
    initParams() {
        // 初始化翻页数据
        this.searchData.left.data = '';
        this.searchData.left.temp = '';
        this.searchData.right.data = '';
        this.searchData.right.temp = '';

        // 初始化翻页数据
        this.page.left.currentPage = 1;
        this.page.right.currentPage = 1;

        // 初始化选中项
        if (this.$refs.leftTable) {
            (this.$refs.leftTable as any).clearSelection();
        }
        if (this.$refs.rightTable) {
            (this.$refs.rightTable as any).clearSelection();
        }
        this.selections = {
            leftSelectedArr: [],
            rightSelectedArr: [],
        };
    }

    /**
     * 初始化方法
     */
    initData() {
        this.initParams();
        this.getLeftTableAllData();
    }

    leftHandleSelected(data) {
        this.selections.leftSelectedArr = data;
    }

    rightHandleSelected(data) {
        this.selections.rightSelectedArr = data;
    }

    // 左边选择每页条数
    leftHandleSizeChange(val) {
        this.page.left.pageSize = val;
        this.getLeftTableAllData(false);
    }

    // 右边选择每页条数
    rightHandleSizeChange(val) {
        this.page.right.pageSize = val;
    }

    mounted() {
        this.rightInitLen = this.filterRightTableAllData.length;
    }

    isFullFiveThousands() {
        // 一次编辑最多往右边移动 5000条
        return this.filterRightTableAllData.length - this.rightInitLen >= this.MOVE_MAX_LEN;
    }

    /* 从左向右最多MOVE_MAX_LEN */
    selectable(row, index) {
        // 需求：如果通过勾选数据再点击移动，限制最多勾选5000条数据，超出5000条无法再继续勾选。
        let isSelected = (this.$refs.leftTable as any).selection.includes(row);
        return !(this.MOVE_MAX_LEN > 0 && (this.$refs.leftTable as any).selection.length >= this.MOVE_MAX_LEN) || isSelected;
    }

    async updateData() {
        let needData = [];

        const rightData = this.getRightAllData();
        if (this.idName.length == 1) {
            rightData.map((item: any) => {
                needData.push(item.issueCode);
            });
            await this.$axios.post(this.url2 + this.grCode, needData).then((res: any) => {
                return res;
            });
        } else {
            rightData.map((item: any) => {
                needData.push({
                    issueCode: item.issueCode,
                    issueName: item.issueName,
                    groupCode: this.grCode,
                });
            });
            await this.$axios
                .post(this.url2, {
                    groupCode: this.grCode,
                    issueList: needData,
                })
                .then((res: any) => {
                    return res;
                });
        }
        console.log(rightData, 'rightData');
    }
}
</script>
<style lang="scss" scoped>
.trant {
    width: 100%;
    height: 100%;
    margin: auto;
    // position: relative;
    display: flex;
    .trant-left,
    .trant-right {
        width: 45%;
        height: 100%;
        .trant-content {
            border: 1px solid #eee;
            width: 100%;
            height: 95%;
            margin-top: 10px;
            .content-input {
                width: 100%;
                height: 40px;
                margin-top: 10px;
                background: #fff;
                padding-top: 4px;
                padding-left: 10px;
                // position: relative;
                .left-p {
                    // position: absolute;
                    // right: 0;
                    // top: 4px;
                    // display: inline-block;
                    .el-icon-search {
                        color: #fff;
                    }
                }
                & /deep/ .el-button {
                    padding: 6px;
                }
            }
        }
    }
    .trant-but {
        width: 10%;
        margin: auto;
        // position: absolute;
        // top: 50%;
        // left: 45%;
        // transform: translate(0, -50%);
        .el-button {
            width: 80%;
            margin-left: 10%;
            margin-top: 10px;
        }
    }
    .trant-right {
        // position: absolute;
        // top: 0;
        // right: 0;
    }
}
/deep/ .el-pagination .el-select .el-input {
    width: 80px;
    .el-input__inner {
        padding: 0px;
        background: none;
        border: 1px solid #e5e5ea;
    }
}
</style>
